/**
 * File: hash_table.c
 * 哈希表，不考虑哈希冲突
 */

#include "hash_table.h"

int hash_func(const int key) // 哈希函数
{
  return key % MAX_SIZE;
}

HashTable *init_hash_table(void) // 初始化空哈希表
{
  HashTable *table;
  table = (HashTable *)malloc(sizeof(HashTable));
  for (int i = 0; i < MAX_SIZE; i++) table->buckets[i] = NULL;
  return table;
}

void append_pair(HashTable *table, const int k, const char *val) // 添加键值对
{
  Pair *p;
  p = (Pair *)malloc(sizeof(Pair));
  p->key = k;
  p->value = (char *)malloc(strlen(val) + 1);
  p->value = strcpy(p->value, val);
  int index = hash_func(k);
  table->buckets[index] = p;
}

void remove_pair(HashTable *table, const int k) // 删除键值对
{
  int index = hash_func(k);
  Pair *p = table->buckets[index];
  free(p->value);
  free(p);
  table->buckets[index] = NULL;
}

char *get_value(const HashTable *table, const int k) // 通过键获取值
{
  int index = hash_func(k);
  Pair *p = table->buckets[index];
  if (p) return p->value;
}

List *get_keys(HashTable *table) // 获取所有键
{
  int *keys;
  Pair *p;
  int len = 0;
  int i;
  List *k_list;

  int index = 0;
  for (i = 0; i < MAX_SIZE; i++)
  {
    p = table->buckets[i];
    if (p) len++;
  }
  keys = malloc(sizeof(int) * len);
  k_list = malloc(sizeof(List));
  for (i = 0; i < MAX_SIZE; i++)
  {
    p = table->buckets[i];
    if (p)
    {
      keys[index] = p->key;
      index++;
    }  
  }
  k_list->items = keys;
  k_list->length = len;
  return k_list;
}

List *get_values(HashTable *table) // 获取所有值
{
  char **vals;
  int len = 0;
  int i;
  List *v_list;
  int index = 0;
  Pair *p;
  for (i = 0; i < MAX_SIZE; i++)
  {
    p = table->buckets[i];
    if (p) len++;
  }
  vals = malloc(sizeof(char *) * len);
  for (i = 0; i < MAX_SIZE; i++)
  {
    p = table->buckets[i];
    if (p)
    {
      vals[index] = p->value;
      index++;
    }  
  }
  v_list = malloc(sizeof(List));
  v_list->items = vals;
  v_list->length = len;
  return v_list;
}

void print_hash_table(const HashTable *table) // 打印
{
  printf("{ ");
  Pair *p;
  for (int i = 0; i < MAX_SIZE; i++)
  {
    p = table->buckets[i];
    if (p) printf("\n\t%d: %s,", p->key, p->value);
  }
  puts("\n}");
}

void destory_list(List *list) // 销毁List
{
  free(list->items);
  free(list);
}

void destory_hash_table(HashTable *table) // 销毁哈希表
{
  Pair *p;
  for (int i = 0; i < MAX_SIZE; i++)
  {
    p = table->buckets[i];
    if (p) free(p->value);
    free(p);
  }
  free(table);
}